package com.briup.pai.interceptor;

import com.briup.pai.common.constant.LoginConstant;
import com.briup.pai.common.enums.ResultCodeEnum;
import com.briup.pai.common.exception.BriupAssert;
import com.briup.pai.common.exception.CustomException;
import com.briup.pai.common.utils.JwtUtil;
import com.briup.pai.common.utils.SecurityUtil;
import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        // 验证token的有效性
        // 放行options的方法
        if (request.getMethod().equalsIgnoreCase("options")) {
            return true;
        }
        // 判断处理器类型
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 获取token
        // 注意使用“token”还是“Authorization”取决于前端怎么封装的
        String token = request.getHeader(LoginConstant.TOKEN_NAME);
        // 验证token的有效性
        try {
            BriupAssert.requireNotNull(token, ResultCodeEnum.USER_NOT_LOGIN);
        }catch (ExpiredJwtException e){
            // 判断token过期
            throw new CustomException(ResultCodeEnum.USER_LOGIN_EXPIRATION);
        }

        // 因为后面的操作要共享其中的信息，使用ThreadLocal
        // 获取token中的id
        Integer userId = JwtUtil.getUserId(token);
        SecurityUtil.setUserId(userId);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) throws Exception {
        // 从ThreadLocal中移除数据
        SecurityUtil.removeUserId();
    }
}
